package com.iwhalecloud.bss.kite.cucc.web.controller.scene;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.api.job.cop.ICOPMemberCommitService;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.operate.ICuccOperateSceneOfferInstService;
import com.iwhalecloud.bss.kite.cucc.client.dto.goods.GoodsMemberDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.goods.MemberGoodDTO;
import com.iwhalecloud.bss.kite.cucc.service.util.ProdCateUtil;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.transaction.TransactionContext;
import com.iwhalecloud.bss.kite.service.scene.bo.OperateSceneMainOfferInstBO;
import com.iwhalecloud.bss.kite.web.service.accept.util.AcceptEngineUtil;
import com.ztesoft.zsmart.core.log.ZSmartLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneOfferInstService;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneProdInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.cust.CustDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdRoleModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProductModuleVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.web.service.ISceneService;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferDetailCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferDetail;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRelInfo;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.service.context.ServiceContext;
import com.iwhalecloud.bss.kite.service.scene.bo.OperateSceneBO;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/cuccOfferRole")
@Api(tags = {"/cuccOfferRole - 销售品角色成员操作"
})
public class CuccOfferRoleController {
    private static final ZSmartLogger LOGGER = ZSmartLogger.getLogger(CuccOfferRoleController.class);

    @Autowired
    private IOperateSceneOfferInstService operateSceneOfferInstService;

    @Autowired
    private ICuccOperateSceneOfferInstService cuccOperateSceneOfferInstService;

    @Autowired
    private IOperateSceneProdInstService operateSceneProdInstService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private OperateSceneMainOfferInstBO operateSceneMainOfferInstBO;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private ISceneService sceneService;

    @Autowired
    private IGoodsService goodsService;

    @KiteTransactional
    @ApiOperation(value = "新增销售品成员", notes = "新增销售品成员")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例ID", required = true),
        @ApiImplicitParam(name = "parentOfferInstId", value = "父级销售品实例ID", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品ID", required = true),
        @ApiImplicitParam(name = "custId", value = "客户ID", required = true)
    })
    @PostMapping
    public DataResult<List<ProductModuleVO>> addOfferRole(@RequestParam String sceneInstId, @RequestParam String parentOfferInstId,
        @RequestParam String offerId, @RequestParam String templateId, @RequestParam String custId) {
        Offer offer = OfferCache.get(offerId);
        if (Objects.isNull(offer)) {
            ErrorConsts.OFFER_NOT_EXISTS.throwOut(offerId);
        }
        List<OfferDetail> offerDetails = OfferDetailCache.get(offerId);

        // 是否是双线删除的产品再次新增（恢复删除的产品）
        boolean flag = false;
        KiteOfferInst kiteOfferInst = null;
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        String catagoryId = CuccPosServiceUtils.getCateId(sceneInstId, custId);
        if(KiteStringUtils.equalsAny(catagoryId, ProdCateUtil.getDoubleLineCateIdForArr())
            && KiteStringUtils.isEqual(sceneInst.getServiceOfferId(), "1024") && KiteListUtils.isNotEmpty(offerDetails)) {
            // 附加商品变更，五大双线附加商品删除后新增，按修改处理，还原已删除的附加商品
            List<KiteOfferInst> kiteOfferInsts = querySceneInstService.listMainOfferInsts(sceneInstId, offerId);
            kiteOfferInst = kiteOfferInsts.stream().filter(offerInst ->
                KiteStringUtils.isEqual(offerInst.getActionType().name(), ActionType.D.name())
                    && KiteStringUtils.isEqual(offerInst.getOriginalActionType().name(), ActionType.K.name())
            ).findAny().orElse(null);

            String productId = offerDetails.get(0).getObjId();
            List<KiteProdInst> kiteProdInsts = querySceneInstService.listProdInstsByProdId(sceneInstId, productId);
            KiteProdInst kiteProdInst = kiteProdInsts.stream().filter(prodInst ->
                KiteStringUtils.isEqual(prodInst.getActionType().name(), ActionType.D.name())
                    && KiteStringUtils.isEqual(prodInst.getOriginalActionType().name(), ActionType.K.name())
            ).findAny().orElse(null);

            // 用户实例存在的附加商品，删除了，再勾选，恢复删除的产品
            if(Objects.nonNull(kiteOfferInst) && Objects.nonNull(kiteProdInst)) {
                flag = true;
                operateSceneInstService.rollbackByInst(sceneInstId, InstType.PROD_INST, kiteProdInst.getProdInstId());
                operateSceneInstService.rollbackByInst(sceneInstId, InstType.MAIN_OFFER_INST, kiteOfferInst.getInstId());
                // 还原属性值
                List<KiteProdInst> prodInsts = querySceneInstService.listProdInstsFromOfferInstByProdId(custId, kiteOfferInst.getOfferInstId(), productId);
                List<KiteOfferInst> additionalOfferInsts = querySceneInstService.listAdditionalOfferInstsFromOfferInst(custId, kiteOfferInst.getOfferInstId());
                prodInsts.forEach(prodInst -> {
                    prodInst.setActionType(prodInst.getOriginalActionType());
                    prodInst.listAttrs().forEach(kiteAttr -> {
                        if (KiteStringUtils.equalsAny(kiteAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M) && !KiteStringUtils.isEqual(kiteAttr.getValue(), kiteAttr.getOriginValue())) {
                            kiteAttr.setValue(kiteAttr.getOriginValue());
                        }
                    });
                    TransactionContext.getContainer().putInst(prodInst);
                });
                additionalOfferInsts.forEach(offerInst -> {
                    offerInst.setActionType(offerInst.getOriginalActionType());
                    offerInst.listAttrs().forEach(kiteAttr -> {
                        if (KiteStringUtils.equalsAny(kiteAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M) && !KiteStringUtils.isEqual(kiteAttr.getValue(), kiteAttr.getOriginValue())) {
                            kiteAttr.setValue(kiteAttr.getOriginValue());
                        }
                    });
                    TransactionContext.getContainer().putInst(offerInst);
                });
            }
        }

        if(!flag) {
            kiteOfferInst = operateSceneOfferInstService
                .addOfferInst(sceneInstId, parentOfferInstId, offerId, null, custId, ContextUtil.getUserId().toString())
                .getResultObject();
        }

        if (Objects.isNull(kiteOfferInst)) {
            return ErrorConsts.SUCCESS.getResult(Lists.newArrayList());
        }

        // 设置附加商品的主商品编码和名称，用户中心落户需要
        KiteOfferInst parentOfferInst = this.querySceneInstService.getOfferInst(custId, parentOfferInstId);
        if (!KiteObjectUtils.isEmpty(parentOfferInst)) {
            CuccPosServiceUtils.setExtParamValue(kiteOfferInst, sceneInstId, "saleGoodsCode", parentOfferInst.getAttrValue("saleGoodsCode"));
            CuccPosServiceUtils.setExtParamValue(kiteOfferInst, sceneInstId, "saleGoodsName", parentOfferInst.getAttrValue("saleGoodsName"));
            if(flag) {
                // 刷新场景
                DataResult<Boolean> dataResult = ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
                AcceptEngineUtil.refreshScene(dataResult);
            } else {
                this.operateSceneInstService.addInst(sceneInstId, kiteOfferInst);
            }
        }

        if (KiteListUtils.isEmpty(offerDetails)) {
            return ErrorConsts.SUCCESS.getResult(Lists.newArrayList());
        }
        CustDTO custInfo = ServiceContext.getCust(sceneInst.getSceneInstId(), custId);
        List<ProductModuleVO> prodModuleVos = Lists.newArrayList();
        OperateSceneBO operateSceneBO = SpringUtil.getBean(OperateSceneBO.class);
        for (OfferDetail detail : offerDetails) {
            ProductModuleVO prodModule = new ProductModuleVO();
            prodModule.setProdId(detail.getObjId());
            prodModule.setProdName(
                Optional.ofNullable(ProductCache.get(detail.getObjId())).map(Product::getProdName).orElse(""));
            prodModule.setOfferId(offerId);
            prodModule.setOfferName(Optional.ofNullable(OfferCache.get(offerId)).map(Offer::getOfferName).orElse(""));
            prodModule.setOfferInstId(kiteOfferInst.getOfferInstId());

            List<ProdRoleModuleVO> prodRoles = Lists.newArrayList();
            List<KiteProdInst> prodInsts = querySceneInstService
                .listProdInstsFromOfferInstByProdId(custId, kiteOfferInst.getOfferInstId(), detail.getObjId());
            for (KiteProdInst prodInst : prodInsts) {
                ProdRoleModuleVO prodRoleModuleVO = new ProdRoleModuleVO();
                // 先临时解决问题
                if(!flag) {
                    operateSceneBO.executeProdInstAttrAfter(custId, sceneInst, custInfo, prodInst.getProdInstId());
                }
                prodRoleModuleVO.setProdInstId(prodInst.getProdInstId());
                //如果回刷 这里就不用组装了
                ProdRoleModuleVO prodRole = sceneService
                    .getProdRoleModuleVO(detail.getRoleId(), prodInst.getProdId(), prodInst.getProdInstId(), templateId,
                        offerId).getResultObject();

                if (!KiteObjectUtils.isEmpty(prodRole.getProdAttr()) && KiteListUtils
                    .isNotEmpty(prodRole.getProdAttr().getProdAttrList())) {
                    prodRole.getProdAttr().getProdAttrList()
                        .removeIf(attr -> KeyConsts.PROD_ATTR_SHOW_TYPE_E.equals(attr.getShowType()));
                }
                prodRoles.add(prodRole);
            }
            prodModule.setProdRole(prodRoles);
            List<OfferRelInfo> offerRelInfoList = OfferCache.get(offerId).listAllOfferRels().stream().filter(offerRelInfo -> {
                return CoreDataOffer.OFF_0005_12.equals(offerRelInfo.getzOfferType());
            }).collect(Collectors.toList());
            if (KiteListUtils.isNotEmpty(offerRelInfoList)) {
                prodModule.setExtOfferId("true");
            }
            prodModuleVos.add(prodModule);
        }
        return ErrorConsts.SUCCESS.getResult(prodModuleVos);
    }

    @KiteTransactional
    @ApiOperation(value = "新增销售品成员", notes = "新增销售品成员")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例ID", required = true),
        @ApiImplicitParam(name = "parentOfferInstId", value = "父级销售品实例ID", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品ID", required = true),
        @ApiImplicitParam(name = "custId", value = "客户ID", required = true)
    })
    @PostMapping("/addMemOfferRole")
    public DataResult<List<ProductModuleVO>> addMemOfferRole(@RequestParam String sceneInstId, @RequestParam String parentOfferInstId,
                                                          @RequestParam String offerId, @RequestParam String templateId, @RequestParam String custId) {
        Offer offer = OfferCache.get(offerId);
        if (Objects.isNull(offer)) {
            ErrorConsts.OFFER_NOT_EXISTS.throwOut(offerId);
        }

        List<KiteInst> memOfferInsts = this.querySceneInstService.listInsts(sceneInstId, Lists.newArrayList(InstType.MEM_OFFER_INST)).stream().filter(offerInst -> {
            return KiteStringUtils.equalsAny(offerInst.getActionType().name(), ActionType.K.name(), ActionType.A.name(), ActionType.M.name());
        }).collect(Collectors.toList());
        if (!KiteListUtils.isEmpty(memOfferInsts)) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("只能订购一个成员商品");
        }

        KiteOfferInst kiteOfferInst = cuccOperateSceneOfferInstService
            .addMemOfferInst(sceneInstId, parentOfferInstId, offerId, OfferCache.get(offerId).getCateId(), custId, ContextUtil.getUserId().toString())
            .getResultObject();

        if (Objects.isNull(kiteOfferInst)) {
            return ErrorConsts.SUCCESS.getResult(Lists.newArrayList());
        }

        // 设置附加商品的主商品编码和名称，用户中心落户需要
        KiteOfferInst parentOfferInst = this.querySceneInstService.getOfferInst(custId, parentOfferInstId);
        if (!KiteObjectUtils.isEmpty(parentOfferInst)) {
            CuccPosServiceUtils.setExtParamValue(kiteOfferInst, sceneInstId, "saleGoodsCode", parentOfferInst.getAttrValue("saleGoodsCode"));
            CuccPosServiceUtils.setExtParamValue(kiteOfferInst, sceneInstId, "saleGoodsName", parentOfferInst.getAttrValue("saleGoodsName"));
            this.operateSceneInstService.addInst(sceneInstId, kiteOfferInst);
        }
        return ErrorConsts.SUCCESS.getResult(Lists.newArrayList());
    }

    @KiteTransactional
    @ApiOperation(value = "删除销售品成员", notes = "删除销售品成员")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例ID", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品ID", required = true),
        @ApiImplicitParam(name = "offerInstId", value = "销售品实例ID", required = true),
        @ApiImplicitParam(name = "custId", value = "客户ID", required = true)
    })
    @DeleteMapping
    public DataResult<Boolean> deleteOfferRole(@RequestParam String sceneInstId, @RequestParam String offerId,
        @RequestParam String offerInstId, @RequestParam String custId) {
        String offerType = OfferCache.get(offerId).getOfferType();
        List<KiteProdInst> prodInsts = this.querySceneInstService.listProdInstsFromOfferInst(custId, offerInstId);
        if (!KiteListUtils.isEmpty(prodInsts)) {
            for (KiteProdInst prodInst : prodInsts) {
                operateSceneProdInstService.removeProdInst(sceneInstId, prodInst.getProdInstId());
            }
        }
        operateSceneOfferInstService.removeMemOffer(sceneInstId, custId, offerInstId, offerType);
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    @KiteTransactional
    @ApiOperation(value = "更新销售品属性", notes = "更新销售品属性")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例id", required = false),
        @ApiImplicitParam(name = "offerInstId", value = "销售品实例id", required = true),
        @ApiImplicitParam(name = "fieldName", value = "字段名", required = true),
        @ApiImplicitParam(name = "attrValue", value = "修改值", required = true),
        @ApiImplicitParam(name = "attrValueDesc", value = "修改值名称", required = false),
    })
    @PostMapping("/offerAttr")
    public DataResult<Boolean> saveOfferAttr(@RequestParam(required = false) String sceneInstId,
                                             @RequestParam String offerInstId,
                                             @RequestParam String fieldName,
                                             @RequestParam String attrValue,
                                             @RequestParam(required = false) String attrValueDesc) {
        return  operateSceneOfferInstService.updateOfferInstAttr(sceneInstId, offerInstId, fieldName, attrValue, attrValueDesc, KiteWebContext.getContext().getCustId(), ContextUtil.getUserId().toString());
    }

    @ApiOperation(value = "COP成员产品查询", notes = "COP成员产品查询")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "goodsSku", value = "商品id", required = true)
    })
    @PostMapping("/copMembers")
    public DataResult<List<GoodsMemberDTO>> queryCopGoodsMember(@RequestParam String goodsSku) {
        String custId = KiteWebContext.getContext().getCustId();
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();

        List<MemberGoodDTO> selectedMemberGoods = Lists.newArrayList();
        List<MemberGoodDTO> notSelectedMemberGoods = Lists.newArrayList();

        List<GoodsMemberDTO> goodsMemberDTOS = goodsService.queryGoodsMember(goodsSku).getResultObject();

        //List<GoodsMemberDTO> goodsMemberDTOS = CuccOfferMemberCache.get(goodsSku);
        if (!KiteListUtils.isEmpty(goodsMemberDTOS)) {
            goodsMemberDTOS.forEach(goodsCat -> {
                for (MemberGoodDTO memberGood : goodsCat.getMemberGoods()) {
                    List<KiteOfferInst> offerInsts = this.querySceneInstService.listMemOfferInsts(sceneInstId, memberGood.getGoodsSku()).stream().filter(offerInst -> {
                        return KiteStringUtils.equals(offerInst.getActionType().name(), ActionType.A.name());
                    }).collect(Collectors.toList());
                    if (!KiteListUtils.isEmpty(offerInsts)) {
                        offerInsts.forEach(inst -> {
                            MemberGoodDTO memberGood1 = new MemberGoodDTO();
                            KiteBeanUtils.copyProperties(memberGood, memberGood1);
                            memberGood1.setInstId(inst.getOfferInstId());
                            selectedMemberGoods.add(memberGood1);
                        });
                    }
                    else{
                        notSelectedMemberGoods.add(memberGood);
                    }
                }
            });

            goodsMemberDTOS.clear();
            GoodsMemberDTO selectedGoods = new GoodsMemberDTO();
            selectedGoods.setMemberName("已选产品");
            selectedGoods.setMemberGoods(selectedMemberGoods);
            goodsMemberDTOS.add(selectedGoods);

            GoodsMemberDTO notSelectedGoods = new GoodsMemberDTO();
            notSelectedGoods.setMemberName("可选产品");
            notSelectedGoods.setMemberGoods(notSelectedMemberGoods);
            goodsMemberDTOS.add(notSelectedGoods);
        }
        return ErrorConsts.SUCCESS.getResult(goodsMemberDTOS);
    }

    @ApiOperation(value = "COP成员产品删除", notes = "COP成员产品删除")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "offerInstId", value = "成员产品实例id", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例id")
    })
    @PostMapping("/delCopMember")
    public DataResult<Boolean> deleteCopGoodsMember(@RequestParam String offerInstId, @RequestParam String sceneInstId) {
        //SpringUtil.getBean(ICOPMemberCommitService.class).addMember();
        try {
            //SpringUtil.getBean(IBatchAcceptAdjustmentService.class).commitJob();
            SpringUtil.getBean(ICOPMemberCommitService.class).addMember();
        }
        catch (Exception e) {
            LOGGER.error(e);
        }
        return ErrorConsts.SUCCESS.getResult(true);
        //KiteSceneInst sceneInst = this.querySceneInstService.getSceneInst(sceneInstId);
        //return ErrorConsts.SUCCESS.getResult(operateSceneMainOfferInstBO.removeMainOfferInst(sceneInstId,offerInstId,sceneInst.getCustId(),sceneInst.getStaffId()));
    }

}
